package com.bdsoft.actions.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketClientProtocolHandler;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MyClient {
    private final String host;
    private final int port;
    private Channel channel;
    private Robot robot;
    private ScheduledExecutorService scheduler;

    public MyClient(String host, int port) throws Exception {
        this.host = host;
        this.port = port;
        this.robot = new Robot();
    }

    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            URI uri = new URI("ws://" + host + ":" + port + "/ws");
            // 1. 创建WebSocket客户端Bootstrap
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws URISyntaxException {
                            ChannelPipeline pipeline = ch.pipeline();
                            // 1.1 HTTP编解码器（WebSocket基于HTTP升级）
                            pipeline.addLast(new HttpClientCodec());
                            // 1.2 HTTP聚合器（将多个HTTP消息聚合为一个FullHttpRequest/Response）
                            pipeline.addLast(new HttpObjectAggregator(10 * 1024 * 1024)); // 调整为 10MB

                            pipeline.addLast(new WebSocketClientProtocolHandler(uri, WebSocketVersion.V13, null, false, new DefaultHttpHeaders(), 10 * 1024 * 1024));
                            // 1.4 自定义WebSocket客户端处理器（处理业务逻辑）
                            pipeline.addLast(new HandlerClientHello());
                        }
                    });

            // 2. 连接到WebSocket服务器

            ChannelFuture future = bootstrap.connect(uri.getHost(), uri.getPort()).sync();
            channel = future.channel();
            System.out.println("WebSocket客户端已连接到服务器: " + uri);

            // 3. 启动定时任务，每隔2秒发送屏幕截图
            startScheduledTask();

            // 4. 等待连接关闭
            future.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }

    private void startScheduledTask() {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(() -> {
            if (channel != null && channel.isActive()) {
                try {
                    // 3.1 捕获屏幕截图
                    Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
                    BufferedImage screenFullImage = robot.createScreenCapture(screenRect);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    ImageIO.write(screenFullImage, "jpg", baos); // 可以改为 "png" 如果需要无损格式
                    byte[] imageBytes = baos.toByteArray();

                    // 3.2 将截图数据封装为WebSocket二进制帧
                    ByteBuf buffer = Unpooled.wrappedBuffer(imageBytes);
                    BinaryWebSocketFrame frame = new BinaryWebSocketFrame(buffer);

                    // 3.3 发送二进制帧到服务器
                    channel.writeAndFlush(frame);
                    TextWebSocketFrame textFrame = new TextWebSocketFrame("Hello, Server!");
                    channel.writeAndFlush(textFrame);
                    System.out.println("已发送屏幕截图数据，大小: " + imageBytes.length + " bytes");
                } catch (Exception e) {
                    e.printStackTrace();
                    System.err.println("发送屏幕截图失败: " + e.getMessage());
                }
            } else {
                System.err.println("WebSocket连接未就绪，无法发送数据");
            }
        }, 0, 16, TimeUnit.MILLISECONDS); // 初始延迟0秒，之后每2秒执行一次
    }

    public static void main(String[] args) throws Exception {
        MyClient client = new MyClient("127.0.0.1", 18000);
        client.start();
    }
}

